/*
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         佛祖保佑       永无BUG


* @文件说明：HT1621 驱动程序

* @修改记录：   2019/9/9 刘雨
*/
#include "b_drv_ht1621.h"

#include "string.h"
//写
#define LCD_WRITE 0x05
//读
#define LCD_READ 0x06
//命令
#define LCD_COMD 0x04

#define LCD_SYS_EN 0x802
#define LCD_ON 0x806
#define LCD_OFF 0x805
#define LCD_CLK 0x830       //片内定时器
#define HT_LCD_BIAS_1_2 0x850  //偏压选项1/2，4COM
#define HT_LCD_BIAS_1_3 0x852  //偏压选项1/3，4COM
#define LCD_BIAS HT_LCD_BIAS_1_3

typedef struct
{
    uint8_t data[13];
} b_drv_ht1621_user_data_t;

b_ht1621_halif_t  b_ht1621_hal_if = HT1621_HALIF_DEFAULT_CONFIG;
b_ht1621_driver_t b_ht1621_driver = {._hal_if = &b_ht1621_hal_if};

static int _b_ht1621_close(b_ht1621_driver_t *pdrv)
{
    b_ht1621_halif_t *hal_if = pdrv->_hal_if;
    bHalGPIO_Config(hal_if->clck.port, hal_if->clck.pin, B_HAL_GPIO_INPUT, B_HAL_GPIO_NOPULL);
    bHalGPIO_Config(hal_if->data.port, hal_if->data.pin, B_HAL_GPIO_INPUT, B_HAL_GPIO_NOPULL);
    bHalGPIO_Config(hal_if->cs.port, hal_if->cs.pin, B_HAL_GPIO_INPUT, B_HAL_GPIO_NOPULL);
    b_log("ht1621 close\r\n");
    return 0;
}
/******************************************************************************
 *  º¯ÊýÃû: HT1621_Write
 *  ¹¦ÄÜ:     Ð´Êý¾Ý
 *  ÐÎ²Î:     HT1621_HANDLE_T hHandle, ¾ä±ú
            uint16_t unData,  Êý¾Ý
            uint8_t unBitLen    Êý¾ÝµÄÎ»³¤
 *
 *  ·µ»Ø:HAL_StatusTypeDef
 *****************************************************************************/
static int _b_ht1621_write_data(b_ht1621_driver_t *pdrv, uint16_t unData, uint8_t unBitLen)
{
    b_ht1621_halif_t *hal_if = pdrv->_hal_if;

    if (unBitLen > 16)
    {
        return -1;
    }

    uint8_t  i      = 0;
    uint16_t DataWr = unData << (16 - unBitLen);

    for (i = 0; i < unBitLen; i++)
    {
        bHalGPIO_WritePin(hal_if->data.port, hal_if->data.pin, (DataWr & 0x8000) > 0);
        bHalGPIO_WritePin(hal_if->clck.port, hal_if->clck.pin, 0);
        bUtilDelayUS(10);
        bHalGPIO_WritePin(hal_if->clck.port, hal_if->clck.pin, 1);
        bUtilDelayUS(10);
        DataWr <<= 1;
    }
    return 0;
}

/******************************************************************************
 *  函数名: HT1621_WriteCMD
 *  功能:     写数据命令
 *  形参:     HT1621_HANDLE_T hHandle, 句柄
            uint16_t unData,  数据
            uint8_t unBitLen    数据的位长

 *
 *  返回:HAL_StatusTypeDef
 *****************************************************************************/
static int _b_ht1621_write_cmd(b_ht1621_driver_t *pdrv, uint16_t unData, uint8_t unBitLen)
{
    if (unBitLen > 16)
    {
        return -1;
    }
    b_ht1621_halif_t *hal_if = pdrv->_hal_if;

    bHalGPIO_WritePin(hal_if->cs.port, hal_if->cs.pin, 0);
    bUtilDelayUS(10);
    _b_ht1621_write_data(pdrv, unData, unBitLen);
    bHalGPIO_WritePin(hal_if->cs.port, hal_if->cs.pin, 1);

    return 0;
}
/******************************************************************************
 *  函数名: HT1621_WriteCMD
 *  功能:     写数据命令
 *  形参:     HT1621_HANDLE_T hHandle, 句柄
            uint16_t unData,  数据
            uint8_t unBitLen    数据的位长
 *
 *  返回:HAL_StatusTypeDef
 *****************************************************************************/
static int _b_ht1621_write(b_ht1621_driver_t *pdrv, uint32_t addr, uint8_t *pbuf, uint16_t len)
{
    // b_drv_ht1621_user_data_t *user_data = pdrv->_private._p;
    b_ht1621_halif_t *hal_if = pdrv->_hal_if;

    uint8_t i = 0;

    bHalGPIO_WritePin(hal_if->cs.port, hal_if->cs.pin, 0);
    bUtilDelayUS(10);
    _b_ht1621_write_data(pdrv, LCD_WRITE, 3);  //发送写命令
    _b_ht1621_write_data(pdrv, addr, 6);       //发送地址

    for (i = 0; i < len; i++)
    {
        _b_ht1621_write_data(pdrv, pbuf[i], 4);
    }

    bHalGPIO_WritePin(hal_if->cs.port, hal_if->cs.pin, 1);

    return 0;
}

int _b_ht1621_init(void)
{
    b_ht1621_driver.status  = 0;
    b_ht1621_driver.close   = _b_ht1621_close;
    b_ht1621_driver.read    = NULL;
    b_ht1621_driver.ctl     = NULL;
    b_ht1621_driver.open    = NULL;
    b_ht1621_driver.write   = _b_ht1621_write;
    b_ht1621_driver._hal_if = &b_ht1621_hal_if;

    b_ht1621_halif_t *hal_if = b_ht1621_driver._hal_if;

    bHalGPIO_Config(hal_if->clck.port, hal_if->clck.pin, B_HAL_GPIO_OUTPUT, B_HAL_GPIO_PULLUP);
    bHalGPIO_Config(hal_if->data.port, hal_if->data.pin, B_HAL_GPIO_OUTPUT, B_HAL_GPIO_PULLUP);
    bHalGPIO_Config(hal_if->cs.port, hal_if->cs.pin, B_HAL_GPIO_OUTPUT, B_HAL_GPIO_PULLUP);

    bHalGPIO_WritePin(hal_if->clck.port, hal_if->clck.pin, 1);
    bHalGPIO_WritePin(hal_if->data.port, hal_if->data.pin, 1);
    bHalGPIO_WritePin(hal_if->cs.port, hal_if->cs.pin, 1);

    //选择Lcd偏压以及COM口个数
    _b_ht1621_write_cmd(&b_ht1621_driver, LCD_BIAS, 12);
    //选择系统时钟源--片内RC振荡器
    _b_ht1621_write_cmd(&b_ht1621_driver, LCD_CLK, 12);
    _b_ht1621_write_cmd(&b_ht1621_driver, LCD_SYS_EN, 12);
    _b_ht1621_write_cmd(&b_ht1621_driver, LCD_ON, 12);
    b_log("ht1621 init\r\n");
    return 0;
}

bDRIVER_REG_INIT(_b_ht1621_init);
